package com.jyw.business.obstacles.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.google.common.collect.Lists;
import com.jyw.business.obstacles.constant.*;
import com.jyw.business.obstacles.domain.*;
import com.jyw.business.obstacles.domain.dto.web.*;
import com.jyw.business.obstacles.domain.dto.wechat.EvaluateOrderDto;
import com.jyw.business.obstacles.domain.vo.web.MineOrderCountVO;
import com.jyw.business.obstacles.domain.vo.web.MineOrderPageVO;
import com.jyw.business.obstacles.domain.vo.wechat.WxWorkOrderReceiveVO;
import com.jyw.business.obstacles.service.*;
import com.jyw.common.constant.Constants;
import com.jyw.common.event.AstMeteringCompleteEvent;
import com.jyw.common.exception.ServiceException;
import com.jyw.common.exception.ValidationException;
import com.jyw.common.utils.DateUtils;
import com.jyw.common.utils.PageUtils;
import com.jyw.common.utils.SecurityUtils;
import com.jyw.common.utils.StringUtils;
import com.jyw.common.utils.bean.BeanUtils;
import com.jyw.system.domain.SysTeam;
import com.jyw.system.service.ISysUserTeamService;
import com.jyw.system.utils.ConversionUtil;
import com.jyw.system.utils.FileUtils;
import com.jyw.system.utils.TeamUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.jyw.business.obstacles.mapper.ObsOrderMakeMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * 报障-工单处理Service业务层处理
 *
 * @author system
 * @date 2023-08-11
 */
@Service
@Slf4j
public class ObsOrderMakeServiceImpl extends ServiceImpl<ObsOrderMakeMapper, ObsOrderMake> implements IObsOrderMakeService {

    @Resource
    private IObsOrderFaultService orderFaultService;

    @Resource
    private ObsOrderMakeMapper obsOrderMakeMapper;

    @Resource
    private IObsOrderInfoService orderInfoService;

    @Resource
    private IObsOrderSendService orderSendService;

    @Resource
    private IObsOrderProcessService processService;

    @Resource
    private IObsOrderAssistService assistService;

    @Resource
    private IObsOrderEvaluateService iObsOrderEvaluateService;

    @Resource
    private IObsOrderSendService sendService;

    @Resource
    private ISysUserTeamService userTeamService;

    @Resource
    private ApplicationContext applicationContext;

    /**
     * 查询报障-工单处理
     *
     * @param id 报障-工单处理主键
     * @return 报障-工单处理
     */
    @Override
    public ObsOrderMake selectObsOrderMakeById(Long id) {
        return obsOrderMakeMapper.selectObsOrderMakeById(id);
    }

    /**
     * 查询报障-工单处理列表
     *
     * @param obsOrderMake 报障-工单处理
     * @return 报障-工单处理
     */
    @Override
    public List<ObsOrderMake> selectObsOrderMakeList(ObsOrderMake obsOrderMake) {
        return obsOrderMakeMapper.selectObsOrderMakeList(obsOrderMake);
    }

    /**
     * 新增报障-工单处理
     *
     * @param obsOrderMake 报障-工单处理
     * @return 结果
     */
    @Override
    public int insertObsOrderMake(ObsOrderMake obsOrderMake) {
        obsOrderMake.setCreateTime(DateUtils.getNowDate());
        return obsOrderMakeMapper.insertObsOrderMake(obsOrderMake);
    }

    /**
     * 修改报障-工单处理
     *
     * @param obsOrderMake 报障-工单处理
     * @return 结果
     */
    @Override
    public int updateObsOrderMake(ObsOrderMake obsOrderMake) {
        obsOrderMake.setUpdateTime(DateUtils.getNowDate());
        return obsOrderMakeMapper.updateObsOrderMake(obsOrderMake);
    }

    /**
     * 批量删除报障-工单处理
     *
     * @param ids 需要删除的报障-工单处理主键
     * @return 结果
     */
    @Override
    public int deleteObsOrderMakeByIds(Long[] ids) {
        return obsOrderMakeMapper.deleteObsOrderMakeByIds(ids);
    }

    /**
     * 删除报障-工单处理信息
     *
     * @param id 报障-工单处理主键
     * @return 结果
     */
    @Override
    public int deleteObsOrderMakeById(Long id) {
        return obsOrderMakeMapper.deleteObsOrderMakeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receive(ReceiveOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        //校验工单能否接单
        if (!OrderCurrStateConstant.WAIT_ACCEPT.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能接单");
        }
        //判断人员是否为待接单人员
        List<ObsOrderSend> list = sendService.lambdaQuery().eq(ObsOrderSend::getOrderNum, orderDto.getOrderNum()).list();
        //查询当前人员所在的小组
        List<Long> teamIdList = userTeamService.getTeamIdByUser(SecurityUtils.getUserId());
        //获取所有小组集合列表
        List<SysTeam> teamList = TeamUtils.cacheList().stream().filter(data->teamIdList.contains(data.getId())).collect(Collectors.toList());

        List<Long> userTeamList = list.stream().map(data -> {
            if (data.getSendType().equals(1) &&SecurityUtils.getUserId().equals(data.getSendUser())) {
                return Lists.newArrayList(data.getSendTeam());
            }else
            if (data.getSendType().equals(2) && teamIdList.contains(data.getSendTeam())) {
                return Lists.newArrayList(data.getSendTeam());
            } else if (data.getSendType().equals(3) && teamList.stream().filter(team -> data.getSendDept().equals(data.getSendDept())).count() > 0) {
                return teamList.stream().filter(team -> data.getSendDept().equals(data.getSendDept())).map(SysTeam::getId).collect(Collectors.toList());
            }
            return null;
        }).flatMap(Collection::stream).distinct().filter(Objects::nonNull).collect(Collectors.toList());

        if(userTeamList.size()>1&&ObjectUtils.isEmpty(orderDto.getReceiveTeam())){
            throw new ValidationException("请选择你以哪个小组身份接单");
        } else if (userTeamList.size() > 1 && !userTeamList.contains(orderDto.getReceiveTeam())) {
            throw new ValidationException("不能以该小组身份接单");
        }

        //如果只有一个匹配的小组,那么设置所属小组
        if(userTeamList.size()==1){
            orderDto.setReceiveTeam(userTeamList.get(0));
        }


        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.RECEIVING)
                //设置为手动接单
                .processValue("1")
                .build()
        );
        //创建处理信息
        createMakeInfo(fault, SecurityUtils.getUserId(),orderDto.getReceiveTeam());
        //修改状态为处理中
        orderFaultService.lambdaUpdate().eq(ObsOrderFault::getOrderNum,orderDto.getOrderNum())
                .set(ObsOrderFault::getCurrState,OrderCurrStateConstant.PROCESSING).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void complete(CompleteOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能提交完成");
        }
        //判断是否存在子工单但未完成
        List<ObsOrderFault> childOrder = getChildOrder(fault.getOrderNum());
        ArrayList<String> childOrderState = Lists.newArrayList(OrderCurrStateConstant.PROCESSING, OrderCurrStateConstant.WAIT_ACCEPT, OrderCurrStateConstant.SUSPENDED, OrderCurrStateConstant.NOT_PASS_AUDIT);
        if (childOrder.stream().filter(childFault -> !childOrderState.contains(childFault.getCurrState())).findFirst().isPresent()) {
            throw new ValidationException("当前有子工单,不能提交完成");
        }
        //修改处理信息
        ObsOrderMake make = getMakeByOrderNum(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(make)) {
            throw new ServiceException("处理信息不存在");
        }
        BeanUtils.copyProperties(orderDto, make);
        //设置计算属性
        make.setCompleteDate(DateUtils.getNowDate());
        make.setMakeTime((System.currentTimeMillis() - make.getCreateTime().getTime()) / 1000 / 60);
        if (!ObjectUtils.isEmpty(orderDto.getRealTime())) {
            make.setRealTime(orderDto.getRealTime().multiply(new BigDecimal(60)).longValue());
        }
        updateById(make);
        fault.setCurrState(orderFaultService.isAudit(fault.getSource(), fault.getFaultType()) ? OrderCurrStateConstant.WAIT_AUDIT : OrderCurrStateConstant.WAIT_APPRAISAL);
        //判断工单来源如果是工单保养,那么进入待评价时,保养续期
        if(fault.getCurrState().equals(OrderCurrStateConstant.WAIT_APPRAISAL)){
            if(fault.getSource().equals(OrderSourceConstant.AST_METERING)){
                log.info("资产保养完成,发送保养完成事件,资产Id:{}",fault.getAssetsId());
                //保养续期
                applicationContext.publishEvent(new AstMeteringCompleteEvent(fault.getAssetsId()));
            }
        }

        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.COMPLETE)
                .processValue(JSONObject.toJSONString(orderDto))
                .processEnclosure(FileUtils.fileToId(orderDto.getProcessEnclosure()))
                .build()
        );
        orderFaultService.updateById(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void evaluate(EvaluateOrderDto dto) {
        try {
            ObsOrderFault fault = orderFaultService.getFaultByOrder(dto.getOrderNum());
            if (ObjectUtils.isEmpty(fault)) {
                throw new ValidationException("未找到工单");
            }
            if (!OrderCurrStateConstant.WAIT_APPRAISAL.equals(fault.getCurrState())) {
                throw new ValidationException("工单不能评价");
            }
            // 计算评价结果
            setEvaluateResult(dto);
            //记录流程
            processService.record(OrderProcessRecordDto
                    .builder()
                    .orderNum(fault.getOrderNum())
                    .lastFaultState(fault.getCurrState())
                    //操作类型：评价
                    .operState(OrderProcessStateConstant.EVALUATE)
                    .processValue(JSONObject.toJSONString(dto))
                    .processEnclosure(FileUtils.fileToId(dto.getEnclosureList()))
                    .build());
            //新增附件
            iObsOrderEvaluateService.evaluateOrder(dto);
            //修改为已结束
            fault.setCurrState(OrderCurrStateConstant.ENDED);
            orderFaultService.updateById(fault);


        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("评价失败");
        }
    }

    /**
     * 计算评价结果
     *
     * @param dto
     * @return
     */
    private void setEvaluateResult(EvaluateOrderDto dto){
        Double evaluate1=dto.getServiceQuality()==null?0d:dto.getServiceQuality();
        Double evaluate2=dto.getServiceAttitude()==null?0d:dto.getServiceAttitude();
        Double evaluate3=dto.getResponsePrescription()==null?0d:dto.getResponsePrescription();
        Double aDouble = Arrays.asList(evaluate1,evaluate2,evaluate3).stream().mapToDouble( Double :: valueOf ).average().getAsDouble();
        BigDecimal bd = new BigDecimal(aDouble);
        double average = bd.setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        // 5星为非常满意，4-5星为满意，3-4星为较满意，1-3星为不满意。
        if(average == 5){
           dto.setEvaluateResult(1);
        }else if(average<5 &&average>=4 ){
            dto.setEvaluateResult(2);
        }else if(average<4 &&average>=3 ){
            dto.setEvaluateResult(3);
        }else{
            dto.setEvaluateResult(4);
        }
    }

    @Override
    public ObsOrderMake getMakeByOrderNum(String orderNum) {
        List<ObsOrderMake> list = list(new QueryWrapper<ObsOrderMake>()
                .eq(StrUtil.toUnderlineCase(ObsOrderMake.Fields.orderNum), orderNum)
                .eq(StrUtil.toUnderlineCase(ObsOrderMake.Fields.makeState), OrderMakeStateConstant.MASTER)
        );
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public WxWorkOrderReceiveVO getInfoByOrderNum(String orderNum) {
        return obsOrderMakeMapper.getInfoByOrderNum(orderNum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void make(MakeOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能处理");
        }
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .processValue(JSONObject.toJSONString(orderDto))
                .makeState(OrderMakeTypeConstant.MAKING)
                .processEnclosure(FileUtils.fileToId(orderDto.getProcessEnclosure()))
                .build()
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assist(AssistOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能发起协作");
        }
        if (ObjectUtils.isEmpty(orderDto.getAssistList()) || orderDto.getAssistList().size() == 0) {
            throw new ValidationException("协作内容不能为空");
        }
        //创建协作工单
        String assistOrderNum = createAssistOrder(fault, orderDto.getAssistList());
        //创建协作信息
        ObsOrderAssist assist = orderDto.buildAssist(assistOrderNum);
        assistService.save(assist);
        //记录流程
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.ASSIST)
                .processValue(JSONObject.toJSONString(orderDto))
                .build()
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upgrade(OrderUpgradeDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能升级");
        }
        //入库
        orderFaultService.lambdaUpdate().eq(ObsOrderFault::getId, fault.getId()).set(ObsOrderFault::getCurrState, OrderCurrStateConstant.END_UPGRADE).update();
        //子工单结束
        List<ObsOrderFault> childOrder = getChildOrder(orderDto.getOrderNum());
        orderFaultService.updateBatchById(childOrder.stream().map(data -> {
            data.setCurrState(OrderCurrStateConstant.ENDED);
            return data;
        }).collect(Collectors.toList()));
        //记录流程
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.END_UPGRADE)
                .processValue(JSONObject.toJSONString(orderDto))
                .build()
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reback(OrderRebackDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!Lists.newArrayList(OrderCurrStateConstant.PROCESSING
                , OrderCurrStateConstant.WAIT_ACCEPT).contains(fault.getCurrState())) {
            throw new ValidationException("工单不能退单");
        }
        //如果工单在处理中,判断处理人是否是自己
        if (fault.getCurrState().equals(OrderCurrStateConstant.PROCESSING)) {
            ObsOrderMake make = getMakeByOrderNum(orderDto.getOrderNum());
            if (!make.getMakeUser().equals(SecurityUtils.getUserId())) {
                throw new ValidationException("您不是工单处理人,无法退单");
            }
        } else {
            //工单在待接单判断是否自己是待接单人
            if (!orderSendService.isMakeUser(orderDto.getOrderNum(), SecurityUtils.getUserId())) {
                throw new ValidationException("您不是待接单人,无法退单");
            }
        }
        //删除派单信息
        orderSendService.lambdaUpdate().eq(ObsOrderSend::getOrderNum, orderDto.getOrderNum()).remove();
        //设置故障状态为待派单
        orderFaultService.lambdaUpdate()
                .eq(ObsOrderFault::getOrderNum, orderDto.getOrderNum())
                .set(ObsOrderFault::getCurrState, OrderCurrStateConstant.WAIT_DELIVERY).update();
        //记录流程
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.BACK)
                .processValue(JSONObject.toJSONString(orderDto))
                .build()
        );

        //主工单退回后,子工单自动结束
        List<ObsOrderFault> childOrder = getChildOrder(orderDto.getOrderNum());
        orderFaultService.updateBatchById(childOrder.stream().map(data -> {
            data.setCurrState(OrderCurrStateConstant.ENDED);
            return data;
        }).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void suspend(OrderSuspendDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能暂停");
        }
        //记录流程
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.SUSPEND)
                .processValue(JSONObject.toJSONString(orderDto))
                .build());
        //修改为暂停状态
        fault.setCurrState(OrderCurrStateConstant.SUSPENDED);
        orderFaultService.updateById(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void open(BaseOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.SUSPENDED.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能开启");
        }
        //记录流程
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.OPEN_SUSPEND)
                .build());
        //修改为处理状态
        fault.setCurrState(OrderCurrStateConstant.PROCESSING);
        orderFaultService.updateById(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void termination(OrderTerminationDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!Lists.newArrayList(OrderCurrStateConstant.PROCESSING
                , OrderCurrStateConstant.WAIT_ACCEPT
                ,OrderCurrStateConstant.WAIT_DELIVERY
        ).contains(fault.getCurrState())) {
            throw new ValidationException("工单不能终止");
        }
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.END_TERMINATION)
                        .processValue(JSONObject.toJSONString(orderDto))
                .build());
        //修改为暂停状态
        fault.setCurrState(OrderCurrStateConstant.TERMINATED);
        orderFaultService.updateById(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void restart(BaseOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.TERMINATED.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能重启");
        }
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.OPEN_TERMINATION)
                .build());
        //查询该工单最后一条终止时状态
        ObsOrderProcess terminationProcess = processService.lambdaQuery()
                .eq(ObsOrderProcess::getOrderNum, fault.getOrderNum())
                .eq(ObsOrderProcess::getOperState, OrderProcessStateConstant.MAKING)
                .eq(ObsOrderProcess::getMakeState, OrderMakeTypeConstant.END_TERMINATION)
                .orderByDesc(ObsOrderProcess::getId)
                .last("limit 1").one();
        //修改为处理状态
        fault.setCurrState(terminationProcess.getLastFaultState());
        orderFaultService.updateById(fault);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void redirect(OrderRedirectDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.PROCESSING.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能转交");
        }
        if (orderDto.getSendObjType().equals(1) && orderDto.getSendObjId().equals(SecurityUtils.getUserId())) {
            throw new ValidationException("不能转单给自己");
        }
        ObsOrderMake make = getMakeByOrderNum(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(make)) {
            //将处理人置空
            LambdaUpdateChainWrapper<ObsOrderMake> updateChainWrapper = lambdaUpdate()
                    .set(ObsOrderMake::getMakeUser, null)
                    .eq(ObsOrderMake::getId, make.getId());
            update(updateChainWrapper);
        }
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.FORWARD)
                .processValue(JSONObject.toJSONString(orderDto))
                .build());
        //修改状态为待接单
        orderFaultService.lambdaUpdate().eq(ObsOrderFault::getOrderNum,fault.getOrderNum()).set(ObsOrderFault::getCurrState,OrderCurrStateConstant.WAIT_ACCEPT);
        //删除之前的派单数据
        orderSendService.lambdaUpdate().eq(ObsOrderSend::getOrderNum, orderDto.getOrderNum()).remove();
        //查询新的派单数据
        orderSendService.save(orderDto.buildSend(fault));
    }

    /**
     * 创建协作工单
     *
     * @param fault
     * @param assistList
     */
    private String createAssistOrder(ObsOrderFault fault, List<AssistOrderSubDto> assistList) {
        //查询主工单的所有子工单
        List<ObsOrderFault> childFaultList = orderFaultService.list(new QueryWrapper<ObsOrderFault>().eq(StrUtil.toUnderlineCase(ObsOrderFault.Fields.parentOrderNum), fault.getOrderNum()));
        //子工单序号
        int temp = childFaultList.size()+1;
        List<String> assistOrderNum = Lists.newArrayList();
        for (int i = 0; i < assistList.size(); i++) {
            AssistOrderSubDto assistOrder = assistList.get(i);
            //处理工单号
            String childOrderNum = StringUtils.format("{}{}{}",fault.getOrderNum(),"#",temp<10?"0"+temp:temp);
            assistOrderNum.add(childOrderNum);
            //创建异常
            ObsOrderFault orderFault = buildAssistFault(fault, childOrderNum, assistOrder);
            //创建工单信息
            buildAssistOrder(orderFault);
            //创建派单信息
            buildAssistSend(assistOrder, orderFault);
            processService.record(OrderProcessRecordDto
                    .builder()
                    .orderNum(childOrderNum)
                    .operState(OrderProcessStateConstant.CREATE_ORDER)
                    .processValue(OrderSourceConstant.ASSIST.toString())
                    .build());
            temp++;
        }
        return assistOrderNum.stream().collect(Collectors.joining(","));
    }

    /**
     * 创建协作派单信息
     *
     * @param sub
     * @param fault
     * @return
     */
    private ObsOrderSend buildAssistSend(AssistOrderSubDto sub, ObsOrderFault fault) {
        ObsOrderSend send = new ObsOrderSend();
        send.setOrderNum(fault.getOrderNum());
        send.setSendType(sub.getSendObjType());
        switch (send.getSendType()) {
            case 1:
                send.setSendUser(sub.getSendObjId());
                send.setSendTeam(sub.getSendTeam());
                break;
            case 2:
                send.setSendTeam(sub.getSendObjId());
                break;
            case 3:
                send.setSendDept(sub.getSendObjId());
                break;
        }
        send.setCreateTime(DateUtils.getNowDate());
        send.setType(3);
        orderSendService.save(send);
        return send;
    }

    /**
     * 创建协作工单信息
     *
     * @param orderFault
     * @return
     */
    private ObsOrderInfo buildAssistOrder(ObsOrderFault orderFault) {
        ObsOrderInfo parentOrderInfo = orderInfoService.getInfoByOrderNum(orderFault.getParentOrderNum());
        ObsOrderInfo childOrderInfo = new ObsOrderInfo();
        BeanUtils.copyProperties(parentOrderInfo, childOrderInfo, "id", "orderNum", "state", "createTime", "linkedCode", "linkedType");
        childOrderInfo.setOrderNum(orderFault.getOrderNum());
        childOrderInfo.setOrderState(9);
        childOrderInfo.setCreateTime(DateUtils.getNowDate());
        this.orderInfoService.save(childOrderInfo);
        return childOrderInfo;
    }

    /**
     * 创建协作工单异常
     *
     * @param parentFault 上级工单
     * @param orderNum    工单号
     * @param assistOrder 协作工单信息
     * @return
     */
    private ObsOrderFault buildAssistFault(ObsOrderFault parentFault, String orderNum, AssistOrderSubDto assistOrder) {
        ObsOrderFault fault = new ObsOrderFault();
        fault.setOrderNum(orderNum);
        fault.setSource(OrderSourceConstant.ASSIST);
        fault.setFaultRemark(parentFault.getFaultRemark());
        fault.setAssistContent(assistOrder.getContent());
        fault.setAssistEnclosureId(FileUtils.fileToId(assistOrder.getAssistEnclosure()));
        fault.setDegree(parentFault.getDegree());
        fault.setRangeType(parentFault.getRangeType());
        fault.setCurrState(OrderCurrStateConstant.WAIT_ACCEPT);
        fault.setFaultType(parentFault.getFaultType());
        fault.setRecordState(Constants.BOOL_TRUE);
        fault.setParentOrderNum(parentFault.getOrderNum());
        fault.setCreateTime(DateUtils.getNowDate());
        fault.setCreateUser(SecurityUtils.getUserId());
        orderFaultService.save(fault);
        return fault;
    }

    /**
     * 获取子工单异常
     *
     * @param orderNum
     * @return
     */
    @Override
    public List<ObsOrderFault> getChildOrder(String orderNum) {
        return orderFaultService.list(new QueryWrapper<ObsOrderFault>().setEntity(new ObsOrderFault() {{
            setParentOrderNum(orderNum);
        }}));
    }

    @Override
    public void revokeReview(BaseOrderDto orderDto) {
        ObsOrderFault fault = orderFaultService.getFaultByOrder(orderDto.getOrderNum());
        if (ObjectUtils.isEmpty(fault)) {
            throw new ValidationException("未找到工单");
        }
        if (!OrderCurrStateConstant.WAIT_AUDIT.equals(fault.getCurrState())) {
            throw new ValidationException("工单不能撤销审核");
        }
        processService.record(OrderProcessRecordDto
                .builder()
                .orderNum(fault.getOrderNum())
                .lastFaultState(fault.getCurrState())
                .operState(OrderProcessStateConstant.MAKING)
                .makeState(OrderMakeTypeConstant.REVOKE_REVIEW)
                .build());
        //修改为处理状态
        fault.setCurrState(OrderCurrStateConstant.PROCESSING);
        orderFaultService.updateById(fault);
    }

    @Override
    public List<MineOrderPageVO> orderPage(MineOrderPageDto pageDto) {
        pageDto.setSearchUser(SecurityUtils.getUserId());
        List<MineOrderPageVO> mineOrderPageVOS = obsOrderMakeMapper.orderPage(pageDto);
        return ConversionUtil.conversionList(mineOrderPageVOS, MineOrderPageVO.class);
    }


    /**
     * 接单创建处理信息
     * 计算响应时长=接收时间-创单时间
     *
     * @param orderFault
     * @param sendUser
     * @param receiveTeam
     * @return
     */
    private ObsOrderMake createMakeInfo(ObsOrderFault orderFault, Long sendUser, Long receiveTeam) {
        ObsOrderMake obsOrderMake = lambdaQuery().eq(ObsOrderMake::getOrderNum, orderFault.getOrderNum()).one();
        if(ObjectUtils.isEmpty(obsOrderMake)){
            // 创建处理信息(新增)
            obsOrderMake = new ObsOrderMake();
            obsOrderMake.setOrderNum(orderFault.getOrderNum());
            obsOrderMake.setMakeUser(sendUser);
            obsOrderMake.setMakeState(OrderMakeStateConstant.MASTER);
            long useTime = System.currentTimeMillis() - orderFault.getCreateTime().getTime();
            obsOrderMake.setResponseTime((Long) useTime / 1000 / 60);
            obsOrderMake.setCreateUser(SecurityUtils.getUserId());
            obsOrderMake.setCreateTime(DateUtils.getNowDate());
            obsOrderMake.setMakeTeam(receiveTeam);
            //查询是否存在主流程处理信息
            save(obsOrderMake);
        }else{
            //修改
            obsOrderMake.setMakeUser(sendUser);
            long useTime = System.currentTimeMillis() - orderFault.getCreateTime().getTime();
            obsOrderMake.setResponseTime((Long) useTime / 1000 / 60);
            obsOrderMake.setMakeTeam(receiveTeam);
            lambdaUpdate().eq(ObsOrderMake::getId,obsOrderMake.getId())
                    .set(ObsOrderMake::getMakeUser,sendUser)
                    .set(ObsOrderMake::getResponseTime,obsOrderMake.getResponseTime())
                    .set(ObsOrderMake::getMakeTeam,receiveTeam).update()
            ;
        }
        return obsOrderMake;
    }
    @Override
    public MineOrderCountVO orderPageCount() {
        MineOrderCountVO vo = new MineOrderCountVO();
        MineOrderPageDto dto = new MineOrderPageDto();
        dto.setSearchUser(SecurityUtils.getUserId());
        vo.setAll(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.WAIT_ACCEPT);
        vo.setWaitAccept(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.PROCESSING);
        vo.setProcessing(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.WAIT_AUDIT);
        vo.setWaitAudit(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.NOT_PASS_AUDIT);
        vo.setNotPassAudit(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.WAIT_APPRAISAL);
        vo.setWaitAppraisal(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.SUSPENDED);
        vo.setSuspended(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.TERMINATED);
        vo.setTerminated(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.ENDED);
        vo.setEnded(obsOrderMakeMapper.orderPageCount(dto));

        dto.setCurrState(OrderCurrStateConstant.WAIT_ACCEPT);
        vo.setWaitAccept(obsOrderMakeMapper.orderPageCount(dto));
        return vo;
    }
}
